import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

/// 校验日期格式是否符合'yyyy-MM-dd'格式
bool _isValidDateFormat(String date) {
  if (date == null || date.isEmpty) {
    return false;
  }
  // 使用正则表达式校验日期格式
  final RegExp dateRegExp = RegExp(r'^\d{4}-\d{2}-\d{2}$');
  if (!dateRegExp.hasMatch(date)) {
    return false;
  }

  // 进一步校验日期的有效性
  try {
    final List<String> parts = date.split('-');
    final int year = int.parse(parts[0]);
    final int month = int.parse(parts[1]);
    final int day = int.parse(parts[2]);

    if (month < 1 || month > 12) {
      return false;
    }

    if (day < 1 || day > 31) {
      return false;
    }

    // 简单的月份天数检查（不考虑闰年）
    // 30天的月份
    if ((month == 4 || month == 6 || month == 9 || month == 11) && day > 30) {
      return false;
    }

    // 2月特殊处理
    if (month == 2) {
      // 简化的闰年判断：能被4整除但不能被100整除，或者能被400整除
      bool isLeapYear = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
      if (day > (isLeapYear ? 29 : 28)) {
        return false;
      }
    }

    return true;
  } catch (e) {
    return false;
  }
}

class AlarmCallResult<T> {
  final bool status;
  final T data;
  final String msg;

  AlarmCallResult({
    this.status,
    this.data,
    this.msg,
  });
}

/// 闹钟数据模型
class AlarmInfo {
  final int id; // 数据库主键，可为空用于新建记录
  final String alarmId; // 闹钟唯一标识
  final String tag; // 闹钟标签
  final String date; // 日期
  final int hour; // 小时
  final int minute; // 分钟
  final String title; // 标题
  final String body; // 内容
  final bool repeating; // 是否重复

  AlarmInfo({
    this.id,
    @required this.alarmId,
    @required this.tag,
    this.date,
    @required this.hour,
    @required this.minute,
    @required this.title,
    @required this.body,
    this.repeating = false,
  });

  Map<String, dynamic> toMap() {
    return {
      'id': id,
      'alarm_id': alarmId,
      'tag': tag,
      'date': date,
      'hour': hour,
      'minute': minute,
      'title': title,
      'body': body,
      'repeating': repeating ? 1 : 0,
    };
  }

  factory AlarmInfo.fromMap(Map<String, dynamic> map) {
    return AlarmInfo(
      id: map['id'],
      alarmId: map['alarm_id'],
      tag: map['tag'],
      date: map['date'],
      hour: map['hour'],
      minute: map['minute'],
      title: map['title'],
      body: map['body'],
      repeating: map['repeating'] == 1 ? true : false,
    );
  }
}

class FlutterAlarm {
  static const MethodChannel _channel = const MethodChannel('flutter_alarm');

  /// 获取平台版本信息
  static Future<String> get platformVersion async {
    final String version = await _channel.invokeMethod('getPlatformVersion');
    return version;
  }

  /// 检查权限状态（不会弹出权限请求对话框）
  static Future<bool> checkPermission() async {
    final bool result = await _channel.invokeMethod('checkPermission');
    return result;
  }

  /// 请求必要的权限（会弹出权限请求对话框）
  static Future<bool> requestPermission() async {
    final bool result = await _channel.invokeMethod('requestPermission');
    return result;
  }

  /// 去设置通知权限(ios)
  static void settingPermission() async {
    try {
      _channel.invokeMethod('settingPermission');
    } catch (e) {}
  }

  /// 设置一次性闹钟
  static Future<AlarmCallResult<AlarmInfo>> setAlarm(String alarmId, String tag,
      String date, int hour, int minute, String title, String body) async {
    assert(alarmId != null && alarmId.isNotEmpty, 'alarmId不能为空');
    assert(tag != null && tag.isNotEmpty, 'tag不能为空');
    assert(title != null && title.isNotEmpty, 'title不能为空');
    assert(body != null && body.isNotEmpty, 'body不能为空');
    assert(date != null && date.isNotEmpty, 'date不能为空');
    assert(_isValidDateFormat(date), 'date格式不正确，应为yyyy-MM-dd格式');
    assert(hour != null && hour >= 0 && hour < 24, 'hour必须在0-23之间');
    assert(minute != null && minute >= 0 && minute < 60, 'minute必须在0-59之间');
    final AlarmInfo alarm = AlarmInfo(
      alarmId: alarmId,
      tag: tag,
      date: date,
      hour: hour,
      minute: minute,
      title: title,
      body: body,
      repeating: false,
    );
    var result = await _channel.invokeMethod('setAlarm', alarm.toMap());
    var data = result["data"];
    AlarmInfo alarmInfo;
    if (data != null) {
      alarmInfo = AlarmInfo.fromMap(Map<String, dynamic>.from(data));
    }

    var status = result['status'];
    if (Platform.isIOS) status = status == 1 ? true : false;
    return AlarmCallResult(status: status, data: alarmInfo, msg: result['msg']);
  }

  /// 设置每日重复闹钟
  static Future<AlarmCallResult<AlarmInfo>> setRepeatingAlarm(String alarmId,
      String tag, int hour, int minute, String title, String body) async {
    assert(alarmId != null && alarmId.isNotEmpty, 'alarmId不能为空');
    assert(tag != null && tag.isNotEmpty, 'tag不能为空');
    assert(title != null && title.isNotEmpty, 'title不能为空');
    assert(body != null && body.isNotEmpty, 'body不能为空');
    assert(hour != null && hour >= 0 && hour < 24, 'hour必须在0-23之间');
    assert(minute != null && minute >= 0 && minute < 60, 'minute必须在0-59之间');
    final AlarmInfo alarm = AlarmInfo(
      alarmId: alarmId,
      tag: tag,
      hour: hour,
      minute: minute,
      title: title,
      body: body,
      repeating: true,
    );
    var result =
        await _channel.invokeMethod('setRepeatingAlarm', alarm.toMap());
    var data = result["data"];
    AlarmInfo alarmInfo;
    if (data != null) {
      alarmInfo = AlarmInfo.fromMap(Map<String, dynamic>.from(data));
    }
    var status = result['status'];
    if (Platform.isIOS) status = status == 1 ? true : false;
    return AlarmCallResult(status: status, data: alarmInfo, msg: result['msg']);
  }

  ///根据alarm_id和tag取消闹钟.
  static Future<AlarmCallResult<Null>> cancelAlarm(
      String alarmId, String tag) async {
    assert(alarmId != null && alarmId.isNotEmpty, 'alarmId不能为空');
    assert(tag != null && tag.isNotEmpty, 'tag不能为空');
    var result = await _channel.invokeMethod('cancelAlarm', {
      'alarm_id': alarmId,
      'tag': tag,
    });
    var status = result['status'];
    if (Platform.isIOS) status = status == 1 ? true : false;
    return AlarmCallResult(
        status: status, data: result["data"], msg: result['msg']);
  }

  /// 根据tag取消闹钟
  static Future<AlarmCallResult<Null>> cancelAlarmsByTag(String tag) async {
    assert(tag != null && tag.isNotEmpty, 'tag不能为空');
    var result = await _channel.invokeMethod('cancelAlarmsByTag', {'tag': tag});
    var status = result['status'];
    if (Platform.isIOS) status = status == 1 ? true : false;
    return AlarmCallResult(
        status: status, data: result["data"], msg: result['msg']);
  }

  /// 取消所有闹钟
  static Future<AlarmCallResult<Null>> cancelAllAlarms() async {
    var result = await _channel.invokeMethod('cancelAllAlarms');
    var status = result['status'];
    if (Platform.isIOS) status = status == 1 ? true : false;
    return AlarmCallResult(
        status: status, data: result["data"], msg: result['msg']);
  }

  /// 根据tag获取所有已设置的闹钟
  static Future<AlarmCallResult<List<AlarmInfo>>> getAlarmsByTag(
      String tag) async {
    assert(tag != null && tag.isNotEmpty, 'tag不能为空');
    var result = await _channel.invokeMethod('getAlarmsByTag', {'tag': tag});
    List<dynamic> dataList = result["data"];
    List<AlarmInfo> alarmList = dataList
        .map((map) => AlarmInfo.fromMap(Map<String, dynamic>.from(map)))
        .toList();
    var status = result['status'];
    if (Platform.isIOS) status = status == 1 ? true : false;
    return AlarmCallResult(status: status, data: alarmList, msg: result['msg']);
  }

  /// 根据alarm_id和tag获取单个闹钟
  static Future<AlarmCallResult<AlarmInfo>> getAlarmByAlarmId(
      String alarmId, String tag) async {
    assert(alarmId != null && alarmId.isNotEmpty, 'alarmId不能为空');
    assert(tag != null && tag.isNotEmpty, 'tag不能为空');
    var result = await _channel.invokeMethod('getAlarmByAlarmId', {
      'alarm_id': alarmId,
      'tag': tag,
    });
    var data = result["data"];
    AlarmInfo alarmInfo;
    if (data != null) {
      alarmInfo = AlarmInfo.fromMap(Map<String, dynamic>.from(data));
    }
    var status = result['status'];

    if (Platform.isIOS) status = status == 1 ? true : false;

    return AlarmCallResult(status: status, data: alarmInfo, msg: result['msg']);
  }

  /// 获取所有已设置的闹钟.
  static Future<AlarmCallResult<List<AlarmInfo>>> getAllAlarms() async {
    var result = await _channel.invokeMethod('getAllAlarms', {});
    List<dynamic> dataList = result["data"];
    var status = result['status'];
    if (Platform.isIOS) status = status == 1 ? true : false;
    List<AlarmInfo> alarmList = dataList
        .map((map) => AlarmInfo.fromMap(Map<String, dynamic>.from(map)))
        .toList();
    return AlarmCallResult(status: status, data: alarmList, msg: result['msg']);
  }
}
